"""
python3 数据类型
"""

''' 
标准数据类型
    Number（数字）
    String（字符串）
    List（列表）
    Tuple（元组）
    Sets（集合）
    Dictionary（字典）
    不可变数据（四个）：Number（数字）、String（字符串）、Tuple（元组）、Sets（集合）
    可变数据  （两个）：List（列表）、Dictionary（字典）
'''

'''
内置的数据类型转换
略..
'''

# ---------------------------------------- Number（数字） ----------------------------------------
'''
Number（数字）
支持 int、float、bool、complex（复数）
只有一种整数类型 int，表示为长整型，没有 python2 中的 Long
内置的 type() 函数可以用来查询变量所指的对象类型
还可以用 isinstance 来判断
数值的除法（/）总是返回一个浮点数，要获取整数使用//操作符。
在混合计算时，Python会把整型转换成为浮点数
'''
a, b, c, d = 20, 5.5, True, 4 + 3j
print(type(a), type(b), type(c), type(d))
print(isinstance(100, int))
print(2 / 4)   # 除法
print(2 // 4)  # 除法取整
print(2 ** 5)  # 乘方

'''
isinstance 和 type 的区别在于：
type()不会认为子类是一种父类类型
isinstance()会认为子类是一种父类类型
'''
class A:
    pass
class B(A):
    pass
print(isinstance(A(), A))  # returns True
print(type(A()) == A)      # returns True
print(isinstance(B(), A))  # returns True
print(type(B()) == A)      # returns False

# ---------------------------------------- String（字符串） ----------------------------------------
'''
String（字符串）
变量[头下标:尾下标]
索引值以 0 为开始值，-1 为从末尾的开始位置
加号 (+) 是字符串的连接符， 星号 (*) 表示复制当前字符串，紧跟的数字为复制的次数
'''
str = 'Runoob'
print(str)           # 输出字符串
print(str[0:-1])     # 输出第一个到倒数第二个的所有字符
print(str[0])        # 输出字符串第一个字符
print(str[2:5])      # 输出从第三个开始到第五个的字符
print(str[2:])       # 输出从第三个开始的后的所有字符
print(str * 2)       # 输出字符串两次
print(str + "TEST")  # 连接字符串

'''
字符串：
  所有的字符串都是Unicode字符串
  单引号和双引号使用完全相同
  使用三引号可以指定一个多行字符串
  转义符 '\'  
  使用r可以让反斜杠不发生转义  如 r"this is a line with \n" 则\n会显示
  按字面意义级联字符串，如"this " "is " "string"会被自动转换为this is string
  字符串可以用 + 运算符连接在一起，用 * 运算符重复
  字符串有两种索引方式，从左往右以 0 开始，从右往左以 -1 开始
  字符串不能改变
  没有单独的字符类型，一个字符就是长度为 1 的字符串
  字符串的截取的语法格式如下：变量[头下标:尾下标]
'''

'''
转义字符
略..
'''

'''
字符串格式化
略..
'''
print("我叫 %s 今年 %d 岁!" % ('小明', 10))

'''
格式化操作符辅助指令
略..
'''

'''
多行字符串
'''
errHTML = '''
<HTML><HEAD><TITLE>
Friends CGI Demo</TITLE></HEAD>
<BODY><H3>ERROR</H3>
<B>%s</B><P>
<FORM><INPUT TYPE=button VALUE=Back
ONCLICK="window.history.back()"></FORM>
</BODY></HTML>
'''
print(errHTML)

'''
字符串内建函数
略..
'''

# ---------------------------------------- List（列表） ----------------------------------------
'''
List（列表）
变量[头下标:尾下标]
索引值以 0 为开始值，-1 为从末尾的开始位置
加号（+）是列表连接运算符，星号（*）是重复操作
List中的元素是可以改变的
'''
list = ['abcd', 786, 2.23, 'runoob', 70.2]
tinylist = [123, 'runoob']
print(list)             # 输出完整列表
print(list[0])          # 输出列表第一个元素
print(list[1:3])        # 从第二个开始输出到第三个元素
print(list[2:])         # 输出从第三个元素开始的所有元素
print(tinylist * 2)     # 输出两次列表
print(list + tinylist)  # 连接列表
del list[4]             # 删除元素
'''
列表函数&方法
略..
'''

# ---------------------------------------- Tuple（元组） ----------------------------------------
'''
Tuple（元组）
元组中的元素值是不允许删除的，但我们可以使用del语句来删除整个元组
'''
tuple = ('abcd', 786, 2.23, 'runoob', 70.2)
tinytuple = (123, 'runoob')
print(tuple)              # 输出完整元组
print(tuple[0])           # 输出元组的第一个元素
print(tuple[1:3])         # 输出从第二个元素开始到第三个元素
print(tuple[2:])          # 输出从第三个元素开始的所有元素
print(tinytuple * 2)      # 输出两次元组
print(tuple + tinytuple)  # 连接元组
tup1 = ()     # 空元组
tup2 = (20,)  # 一个元素，需要在元素后添加逗号
# del tuple

'''
元组内置函数
略..
'''

# ---------------------------------------- Set（集合） ----------------------------------------
'''
Set（集合）
集合（set）是一个无序不重复元素的序列
基本功能是进行成员关系测试和删除重复元素
可以使用大括号 { } 或者 set() 函数创建集合
创建一个空集合必须用 set() 而不是 { }，因为 { } 是用来创建一个空字典
'''
student = {'Tom', 'Jim', 'Mary', 'Tom', 'Jack', 'Rose'}
print(student)  # 输出集合，重复的元素被自动去掉
# 成员测试
if 'Rose' in student:
    print('Rose 在集合中')
else:
    print('Rose 不在集合中')
# set可以进行集合运算
a = set('abracadabra')
b = set('alacazam')
print(a)
print(a - b)  # a和b的差集
print(a | b)  # a和b的并集
print(a & b)  # a和b的交集
print(a ^ b)  # a和b中不同时存在的元素

# ---------------------------------------- Dictionary（字典） ----------------------------------------
'''
Dictionary（字典）
列表是有序的对象集合，字典是无序的对象集合。两者之间的区别在于：字典当中的元素是通过键来存取的，而不是通过偏移存取
字典是一种映射类型，字典用"{ }"标识，它是一个无序的键(key) : 值(value)对集合
键(key)必须使用不可变类型
在同一个字典中，键(key)必须是唯一的
创建空字典使用 { }
'''
dict = {}
dict['one'] = "1 - 菜鸟教程"
dict[2] = "2 - 菜鸟工具"
tinydict = {'name': 'runoob', 'code': 1, 'site': 'www.runoob.com'}
print(dict['one'])        # 输出键为 'one' 的值
print(dict[2])            # 输出键为 2 的值
print(tinydict)           # 输出完整的字典
print(tinydict.keys())    # 输出所有键
print(tinydict.values())  # 输出所有值
# 构造函数 dict() 可以直接从键值对序列中构建字典如下
print( {x: x ** 2 for x in (2, 4, 6)} )
# print( dict([('Runoob', 1), ('Google', 2), ('Taobao', 3)]) )
# print( dict(Runoob=1, Google=2, Taobao=3) )

'''
字典内置函数&方法
略..
'''
